# 函数
"""
# 不需要访问权限修饰符
# 也不需要返回值类型
def 函数名(参数1,参数2......):
    代码块
    代码块
    代码块
    代码块
    # 如果需要返回值
    return 返回值
"""


# 计算1~n的和
def sum1(n):
    sum = 0
    for i in range(1, n + 1):
        sum += i
    return sum


res = sum1(100)
print(res)


# 计算N的阶乘
# 5!=5*4*3*2*1
# 两种方式：
# 1、循环
def jieCheng(n):
    res = 1
    for i in range(1, n + 1):
        res *= n
        n -= 1
    return res


print(jieCheng(5))


# 2、递归函数
# 尽量避免使用递归函数 能用循环就用循环
# 递归函数需要满足两个条件：
# 自己调用自己
# 停止条件

# 5! = 5 * 4!
# 4! = 4 * 3!
# n! = n * (n-1)!
def jieCheng2(n):
    if n == 1:
        return 1
    return n * jieCheng2(n - 1)


print(jieCheng2(5))


# print(jieCheng2(999)) # 超过最大的递归次数

# 匿名函数
# lambda 表达式
# lambda 参数1,参数2......:返回值
# 计算x的y次方
def ciFang(x, y):
    return x ** y


print(ciFang(2, 3))

n1 = lambda x, y: x ** y

print(n1(2, 3))


# 函数参数的类型
# 位置参数（必选参数）、默认参数、可变参数、关键字参数、命名关键字参数

# 默认参数 y
# 计算x的y次方 如果不传入y则默认计算x的2次方
def cifang2(x, y=2):
    return x ** y


# print(ciFang(2))
print(cifang2(2))
print(cifang2(2, 3))


# print(cifang2(2,3,4))

# 可变参数
# 传入n1就 返回n1
# 传入n1,n2 就 返回n1+n2
# 传入n1,n2,n3 就 返回n1+n2+n3
# 传入n1,n2,......,nn 就 返回n1+n2+n3+......+nn
def sumN(*args):
    print(args, type(args))
    sum = 0
    for i in args:
        sum += i
    print(sum)


sumN(1)
sumN(1, 2)
sumN(1, 2, 3)
sumN(1, 2, 3, 4)
sumN(1, 2, 3, 4, 5, 6, 7, 8, 9)


# 关键字参数
# 注册函数：
# name、age、addr(可选)、phone(可选)
def register(name, age, **kw):
    print(kw, type(kw))


register("张三", '20', addr="大别野", phone="18888888888")


# 命名关键字参数
# name、age、gender(必选)、addr(可选)、phone(可选)
def register2(name, age, **kw):
    if 'gender' in kw.keys():
        print(kw, type(kw))
    else:
        print("请必须输入您的性别")


register2("李华", '22', addr="乡间小草屋", gender='男')


def register3(name, age='18', *args, gender, **kw):
    print(name, age, args, gender, kw)


register3("小红", '18', gender='女')
register3("小红", '18', 1, 2, 3, 4, 5, 6, 7, gender='女')
